package com.isxcode.demo.service;

import com.isxcode.demo.constant.DorisConstants;
import com.isxcode.demo.pojo.ConnectInfo;
import com.mysql.cj.jdbc.result.ResultSetImpl;
import com.mysql.cj.result.DefaultColumnDefinition;
import com.mysql.cj.result.Field;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Service
public class DorisService {

    /**
     * 检查doris是否可以连接
     */
    public Boolean checkDorisLink(ConnectInfo connectInfo) {

        // 检查连接
        if (connectInfo == null
                || Strings.isEmpty(connectInfo.getHost())
                || Strings.isEmpty(connectInfo.getPort())
                || Strings.isEmpty(connectInfo.getUsername())
                || Strings.isEmpty(connectInfo.getPassword())) {
            return false;
        }

        // 读取驱动
        try {
            Class.forName(DorisConstants.MYSQL_DRIVER_CLASS_NAME);
        } catch (ClassNotFoundException e) {
            log.info(e.getMessage());
        }

        // 校验是否可以连接
        try (Connection connection = DriverManager.getConnection(getUrl(connectInfo), connectInfo.getUsername(), connectInfo.getPassword())) {
            return connection != null;
        } catch (SQLException e) {
            log.info(e.getMessage());
            return false;
        }
    }

    public String getUrl(ConnectInfo connectInfo) {

        // 转化jdbcUrl
        // jdbc:mysql://39.103.230.188:30102/data_assets
        String url = "jdbc:mysql://" + connectInfo.getHost() + ":" + connectInfo.getPort();
        if (!Strings.isEmpty(connectInfo.getDatabaseName())) {
            url = url + "/" + connectInfo.getDatabaseName();
        }
        return url;
    }

    public List<String> queryDatabaseNames(ConnectInfo connectInfo) throws Exception {

        if (connectInfo == null
                || Strings.isEmpty(connectInfo.getHost())
                || Strings.isEmpty(connectInfo.getPort())
                || Strings.isEmpty(connectInfo.getUsername())
                || Strings.isEmpty(connectInfo.getPassword())) {
            throw new Exception("参数为空");
        }

        try {
            Class.forName(DorisConstants.MYSQL_DRIVER_CLASS_NAME);
        } catch (ClassNotFoundException e) {
            log.info(e.getMessage());
        }

        try (Connection connection = DriverManager.getConnection(getUrl(connectInfo), connectInfo.getUsername(), connectInfo.getPassword());
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery(DorisConstants.QUERY_DATABASE_NAMES_SQL);) {

            List<String> databaseNames = new ArrayList<>();
            while (resultSet.next()) {
                databaseNames.add(resultSet.getString(1));
            }
            return databaseNames;
        } catch (SQLException e) {
            log.info(e.getMessage());
            throw new Exception("查询异常");
        }
    }

    public List<String> queryTableNames(ConnectInfo connectInfo) throws Exception {

        if (connectInfo == null
                || Strings.isEmpty(connectInfo.getHost())
                || Strings.isEmpty(connectInfo.getPort())
                || Strings.isEmpty(connectInfo.getUsername())
                || Strings.isEmpty(connectInfo.getPassword())
                || Strings.isEmpty(connectInfo.getDatabaseName())) {
            throw new Exception("参数为空");
        }

        try {
            Class.forName(DorisConstants.MYSQL_DRIVER_CLASS_NAME);
        } catch (ClassNotFoundException e) {
            log.info(e.getMessage());
        }

        try (Connection connection = DriverManager.getConnection(getUrl(connectInfo), connectInfo.getUsername(), connectInfo.getPassword());
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery(DorisConstants.QUERY_TABLE_NAMES_SQL);) {

            List<String> databaseNames = new ArrayList<>();
            while (resultSet.next()) {
                databaseNames.add(resultSet.getString(1));
            }
            return databaseNames;
        } catch (SQLException e) {
            log.info(e.getMessage());
            throw new Exception("查询异常");
        }
    }

    public List<List<String>> queryData(ConnectInfo connectInfo, String tableName) throws Exception {

        if (connectInfo == null
                || Strings.isEmpty(connectInfo.getHost())
                || Strings.isEmpty(connectInfo.getPort())
                || Strings.isEmpty(connectInfo.getUsername())
                || Strings.isEmpty(connectInfo.getPassword())
                || Strings.isEmpty(connectInfo.getDatabaseName())) {
            throw new Exception("参数为空");
        }

        try {
            Class.forName(DorisConstants.MYSQL_DRIVER_CLASS_NAME);
        } catch (ClassNotFoundException e) {
            log.info(e.getMessage());
        }

        List<List<String>> data = new ArrayList<>();
        try (Connection connection = DriverManager.getConnection(getUrl(connectInfo), connectInfo.getUsername(), connectInfo.getPassword());
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery("select * from " + tableName);) {

            int colNum = ((DefaultColumnDefinition) ((ResultSetImpl) resultSet).getColumnDefinition()).getFields().length;
            while (resultSet.next()) {
                List<String> metaData = new ArrayList<>();
                for (int i = 1; i <= colNum; i++) {
                    metaData.add(resultSet.getString(i));
                }
                data.add(metaData);
            }
            return data;
        } catch (SQLException e) {
            log.info(e.getMessage());
            throw new Exception("查询异常");
        }
    }

    public List<List<String>> queryColumnNames(ConnectInfo connectInfo, String tableName) throws Exception {

        if (connectInfo == null
                || Strings.isEmpty(connectInfo.getHost())
                || Strings.isEmpty(connectInfo.getPort())
                || Strings.isEmpty(connectInfo.getUsername())
                || Strings.isEmpty(connectInfo.getPassword())
                || Strings.isEmpty(connectInfo.getDatabaseName())) {
            throw new Exception("参数为空");
        }

        try {
            Class.forName(DorisConstants.MYSQL_DRIVER_CLASS_NAME);
        } catch (ClassNotFoundException e) {
            log.info(e.getMessage());
        }

        List<List<String>> columnNames = new ArrayList<>();
        try (Connection connection = DriverManager.getConnection(getUrl(connectInfo), connectInfo.getUsername(), connectInfo.getPassword());
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery("select * from " + tableName);) {

            Field[] fields = ((DefaultColumnDefinition) ((ResultSetImpl) resultSet).getColumnDefinition()).getFields();
            Arrays.asList(fields).forEach(e -> {
                List<String> metaColumn = new ArrayList<>();
                metaColumn.add(e.getName());
                metaColumn.add(e.getMysqlType().getName());
                columnNames.add(metaColumn);
            });

            return columnNames;
        } catch (SQLException e) {
            log.info(e.getMessage());
            throw new Exception("查询异常");
        }
    }

    /**
     * 通过spark yarn 将数据同步到doris上
     */
    public void hiveToDorisByYarn(ConnectInfo connectInfo) {


    }

    public void executeDorisSql(ConnectInfo connectInfo, String sql) throws Exception {

        if (connectInfo == null
                || Strings.isEmpty(connectInfo.getHost())
                || Strings.isEmpty(connectInfo.getPort())
                || Strings.isEmpty(connectInfo.getUsername())
                || Strings.isEmpty(connectInfo.getPassword())
                || Strings.isEmpty(connectInfo.getDatabaseName())) {
            throw new Exception("参数为空");
        }

        try {
            Class.forName(DorisConstants.MYSQL_DRIVER_CLASS_NAME);
        } catch (ClassNotFoundException e) {
            log.info(e.getMessage());
        }

        try (Connection connection = DriverManager.getConnection(getUrl(connectInfo), connectInfo.getUsername(), connectInfo.getPassword());
             Statement statement = connection.createStatement();) {

            statement.execute(sql);
        } catch (SQLException e) {
            log.info(e.getMessage());
            throw new Exception("查询异常");
        }
    }

}
